// ==============================================================
//
//  Copyright (c) 1999-2002 by Alex Vinokur.  This work and all works
//  derived from it may be copied and modified without any
//  restrictions other than that a copy of this copyright notice
//  must be included in any copy of this work or any derived work.
//
// ==============================================================

///////////////////////////////////////

#ifndef service_H
#define service_H

///////////////////////////////////////

static char id_service_H[] = "@(#)## n-ary Huffman Template Algorithm ## Author : Alex Vinokur ## "__FILE__;

// ##############################################################
// =================================
//  n-ary Huffman Template Algorithm
// =================================
//
//  FILE : service.h
//
//  AUTHOR : Alex Vinokur
//
//  DESCRIPTION :
//         Definition and implementation
//         of the following auxiliary template functions : 
//         ----------------------------------------------
//         - string             to_str (...)
//         - void               add_to_vector (...)
//         - void               fill_vector (...)
//         - unsigned int       get_width (...)
//         - string             gstr_vect_ptrs (...)
//         - string             gstr_vector (...)       // two functions
//         - string             gstr_path (...)
//         - string             gstr_map (...)
//         - ostream&           operator<< (...)        // two operators
//         ----------------------------------------------
//
//         Definition of the following auxiliary functions : 
//         -------------------------------------------------
//         - void               show_file (...)
//         -------------------------------------------------
//
// ##############################################################


#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>
#include <functional>
#include <iostream>
#include <fstream>
#include <typeinfo>
#include <iomanip>
#include <assert.h>
using namespace std;

#include "version.h"

// #######################################################
// ##### PART : DEFINES & CONSTANTS ######################
// #######################################################

#define MIN_VALUE(x,y)  ((x) < (y) ? (x) : (y))
#define MAX_VALUE(x,y)  ((x) > (y) ? (x) : (y))
#define ASSERT(x)       if (!(x)) {cerr << endl << endl << "\t=== BUG IN PROGRAM ===" << endl;}; assert (x)

#define FATAL_TITLE     "FATAL ERROR : "
#define FATAL_SHIFT     "            : "
#define FATAL_MSG(x)    cerr << endl \
                             << FATAL_TITLE \
                             << x \
                             << endl \
                             << FATAL_SHIFT \
                             << "File - " \
                             << __FILE__ \
                             << ", Line#" \
                             << __LINE__ \
                             << endl; \
                             exit (1)


#define ERROR_TITLE     "ERROR : "
#define ERROR_SHIFT     "      : "
#define ERROR_MSG(x)    cerr << endl \
                             << ERROR_TITLE \
                             << x \
                             << endl \
                             << ERROR_SHIFT \
                             << "File - " \
                             << __FILE__ \
                             << ", Line#" \
                             << __LINE__ \
                             << endl;


// #######################################################
// ##### PART : typedefs #################################
// #######################################################
typedef unsigned int    CODE;



// #######################################################
// ##### PART : FUNCTIONS ################################
// #######################################################


// #####################################################3
template <typename T>
string to_str (T value_i, int width_i = -1, char fill_i = ' ', const string& prefix_i = string ())
{
string		ret_stringValue;
ostringstream	tmp_osstr;

        // =================================
        tmp_osstr << prefix_i;
        if (width_i > 0)
        {
                tmp_osstr << setw (width_i);
                tmp_osstr << setfill (fill_i);
        }
        tmp_osstr << value_i;

        // =================================
        ret_stringValue = tmp_osstr.str();
        // =================================
        return ret_stringValue;
} // string to_str (T value_i)



// #####################################################3
template <typename T>
void add_to_vector (vector<T>& vector_i, const basic_string<T>& string_i)
{
        copy (string_i.begin (), string_i.end (), back_inserter (vector_i));
} //void add_to_vector (T value_o)



// #####################################################3
template <typename T>
void fill_vector (vector<T>& vector_i, const basic_string<T>& string_i)
{
        vector_i = vector<T> ();
        add_to_vector (vector_i, string_i);
} //void fill_vector (T value_o)




// #####################################################3
template <typename T>
unsigned int get_width (T value_i)
{
unsigned int    ret_intValue;
ostringstream	tmp_osstr;

        tmp_osstr << value_i;

        // =================================
        ret_intValue = string (tmp_osstr.str()).size ();
        // =================================
        return ret_intValue;
} // unsigned int get_width (T value_i)



// #####################################################
template <typename T1>
string   gstr_vect_ptrs (const vector<T1*>& vector_i, const string& delimiter_i = "")
{
ostringstream		tmp_osstr;
string                  tmp_string;
unsigned int            cur_index;

        cout << delimiter_i << endl;
        for (cur_index = 0; cur_index < vector_i.size (); cur_index++)
        {
                cout << "vector element ["
                     << cur_index << "] : "
                     << (*(vector_i [cur_index]))
                     << delimiter_i
                     << endl;
        }


        tmp_string = tmp_osstr.str();

        // ===================
        return tmp_string;

} // gstr_vect_ptrs (const vector<CODE>& vector_i)



// #####################################################
template <typename T1>
string   gstr_vector (const vector<T1>& vector_i, unsigned int start_pos_i = 0, unsigned int end_pos_i = UINT_MAX, const string& delimiter_i = "")
{

        if (vector_i.empty ())
        {
                return "Empty Vector";
        }
        // =====================================
        if (end_pos_i == UINT_MAX)
        {
                end_pos_i = vector_i.size () - 1;
        }
        ASSERT (end_pos_i < vector_i.size ());
        ASSERT (start_pos_i <= end_pos_i);
        // =====================================

string                  	tmp_string;
ostringstream			tmp_osstr;
typename vector<T1>::const_iterator	vect_iter;

        for (vect_iter = (vector_i.begin () + start_pos_i);
             !(vect_iter == (vector_i.begin () + end_pos_i + 1));
             vect_iter++
             )
        {
		tmp_osstr << (*vect_iter);
		tmp_osstr << delimiter_i;
        }

        tmp_string = tmp_osstr.str();

        // ===================
        return tmp_string;

} // gstr_vector (const vector<CODE>& vector_i)



// #####################################################
template <typename T1>
ostream& operator<< (ostream& o, const vector<T1>& vector_i)
{
        return o << gstr_vector (vector_i);
}


// #####################################################
template <typename T1>
string   gstr_vector (const vector<T1>& vector_i, const string& delimiter_i, unsigned int start_pos_i = 0, unsigned int end_pos_i = UINT_MAX)
{
        return gstr_vector (vector_i, start_pos_i, end_pos_i, delimiter_i);
} // string   gstr_vector - 2


// #####################################################
template <unsigned int ARY>
string   gstr_path (const vector<CODE>& path_i)
{
const string    delimiter_CNS = (ARY > 16) ? "." : "";
ostringstream	tmp_osstr;
string          tmp_string;

        if (path_i.empty ())
        {
                tmp_osstr << "This is Huffman Tree Root";
        }
        else
        {
                for (unsigned int cur_index = 0; cur_index < path_i.size (); cur_index++)
                {
                        if (cur_index > 0)
                        {
                                tmp_osstr << delimiter_CNS;
                        }
                        tmp_osstr << path_i [cur_index];
                }
        }
        // =====================================
        tmp_string = tmp_osstr.str();

        // ===================
        return tmp_string;

} // gstr_path (const vector<CODE>& path_i)




// #######################################
template <typename T1, typename T2>
string gstr_map (const map<T1, T2, less<T1> >& map_i, const string &shift_i = string ())
{
ostringstream	tmp_osstr;
string          tmp_string;

        tmp_osstr << endl;
        tmp_osstr << endl;
        tmp_osstr << shift_i;
        tmp_osstr << "\tmap size = "
                      << map_i.size ()
                      << endl;

typename map<T1, T2, less<T1> >::const_iterator  cur_const_iter;
        for (cur_const_iter = map_i.begin(); !(cur_const_iter == map_i.end()); cur_const_iter++)
        {
                tmp_osstr << shift_i;
                tmp_osstr << "map element ["
                              << (*cur_const_iter).first
                              << "] = "
                              << "<"
                              << (*cur_const_iter).second
                              << ">";
                tmp_osstr << endl;
        }
        tmp_string = tmp_osstr.str();

        return tmp_string;

} // string gstr_map



// #####################################################
void   show_file (
	const string& file_type_i, 
	const string& file_name_i, 
	const string& delimiter_i = " "
	);


// #######################################
template <typename T1, typename T2>
ostream& operator<<(ostream &str_o, const map<T1, T2, less<T1> >& map_i)
{
        return str_o << gstr_map (map_i);

} // ostream& operator<<(ostream &str_o, const map<T1>& map_i)


// #######################################################
// ##### PART : CLASSES ##################################
// #######################################################
class ClassLogo
{
	private :
		void	show_logo (const string& msg_i) const;
	public :
		ClassLogo ();
		~ClassLogo ();
};


#endif	// service_H


// #######################################################
// ################ END OF FILE ##########################
// ####################################################### 

